GtkCssPathNode *path_node = GTK_CSS_PATH_NODE (node);
if (path_node->context)
- {
- GtkBitmask *changes;
-
- changes = _gtk_bitmask_new ();
- changes = _gtk_bitmask_invert_range (changes,
- 0,
- _gtk_css_style_property_get_n_properties ());
-
- gtk_style_context_validate (path_node->context, changes);
-
- _gtk_bitmask_free (changes);
- }
+ gtk_style_context_validate (path_node->context, NULL);
}
gboolean
change->n_compared = 0;
change->affects = 0;
- change->has_change = FALSE;
+ change->changes = _gtk_bitmask_new ();
}
void
{
g_object_unref (change->old_style);
g_object_unref (change->new_style);
+ _gtk_bitmask_free (change->changes);
}
GtkCssStyle *
if (!_gtk_css_value_equal (gtk_css_style_get_value (change->old_style, change->n_compared),
gtk_css_style_get_value (change->new_style, change->n_compared)))
{
- change->has_change = TRUE;
change->affects |= _gtk_css_style_property_get_affects (_gtk_css_style_property_lookup_by_id (change->n_compared));
+ change->changes = _gtk_bitmask_set (change->changes, change->n_compared, TRUE);
}
change->n_compared++;
gtk_css_style_change_has_change (GtkCssStyleChange *change)
{
do {
- if (change->has_change)
+ if (!_gtk_bitmask_is_empty (change->changes))
return TRUE;
} while (gtk_css_style_compare_next_value (change));
return FALSE;
}
+gboolean
+gtk_css_style_change_changes_property (GtkCssStyleChange *change,
+ guint id)
+{
+ while (change->n_compared <= id)
+ gtk_css_style_compare_next_value (change);
+
+ return _gtk_bitmask_get (change->changes, id);
+}
+
guint n_compared;
GtkCssAffects affects;
- guint has_change :1;
+ GtkBitmask *changes;
};
void gtk_css_style_change_init (GtkCssStyleChange *change,
gboolean gtk_css_style_change_has_change (GtkCssStyleChange *change);
gboolean gtk_css_style_change_affects (GtkCssStyleChange *change,
GtkCssAffects affects);
+gboolean gtk_css_style_change_changes_property (GtkCssStyleChange *change,
+ guint id);
G_END_DECLS
{
GtkCssWidgetNode *node = GTK_CSS_WIDGET_NODE (object);
- _gtk_bitmask_free (node->accumulated_changes);
+ g_object_unref (node->last_updated_style);
G_OBJECT_CLASS (gtk_css_widget_node_parent_class)->finalize (object);
}
gtk_widget_clear_path (node->widget);
GTK_CSS_NODE_CLASS (gtk_css_widget_node_parent_class)->style_changed (cssnode, change);
-
- node->accumulated_changes = gtk_css_style_add_difference (node->accumulated_changes,
- gtk_css_style_change_get_new_style (change),
- gtk_css_style_change_get_old_style (change));
}
static gboolean
gtk_css_widget_node_validate (GtkCssNode *node)
{
GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node);
- GtkStyleContext *context;
+ GtkCssStyleChange change;
+ GtkCssStyle *style;
if (widget_node->widget == NULL)
return;
- context = _gtk_widget_peek_style_context (widget_node->widget);
- if (context)
- gtk_style_context_validate (context, widget_node->accumulated_changes);
- else
- _gtk_widget_style_context_invalidated (widget_node->widget);
- _gtk_bitmask_free (widget_node->accumulated_changes);
- widget_node->accumulated_changes = _gtk_bitmask_new ();
+ style = gtk_css_node_get_style (node);
+
+ gtk_css_style_change_init (&change, widget_node->last_updated_style, style);
+ if (gtk_css_style_change_has_change (&change))
+ {
+ GtkStyleContext *context;
+
+ context = _gtk_widget_peek_style_context (widget_node->widget);
+ if (context)
+ gtk_style_context_validate (context, &change);
+ else
+ _gtk_widget_style_context_invalidated (widget_node->widget);
+ g_object_unref (widget_node->last_updated_style);
+ widget_node->last_updated_style = g_object_ref (style);
+ }
+ gtk_css_style_change_finish (&change);
}
typedef GtkWidgetPath * (* GetPathForChildFunc) (GtkContainer *, GtkWidget *);
static void
gtk_css_widget_node_init (GtkCssWidgetNode *node)
{
- node->accumulated_changes = _gtk_bitmask_new ();
+ node->last_updated_style = g_object_ref (gtk_css_static_style_get_default ());
}
GtkCssNode *
GtkWidget *widget;
guint validate_cb_id;
- GtkBitmask *accumulated_changes;
+ GtkCssStyle *last_updated_style;
};
struct _GtkCssWidgetNodeClass
/* We need to update the icon surface, but only in case
* the icon theme really changed. */
GtkStyleContext *context = gtk_widget_get_style_context (widget);
- const GtkBitmask *changes = _gtk_style_context_get_changes (context);
- if (!changes || _gtk_bitmask_get (changes, GTK_CSS_PROPERTY_ICON_THEME))
+ GtkCssStyleChange *change = gtk_style_context_get_change (context);
+ if (!change || gtk_css_style_change_changes_property (change, GTK_CSS_PROPERTY_ICON_THEME))
change_icon_theme (GTK_FILE_CHOOSER_BUTTON (widget));
}
}
static void
gtk_image_style_updated (GtkWidget *widget)
{
- static GtkBitmask *affects_icon = NULL;
GtkImage *image = GTK_IMAGE (widget);
GtkImagePrivate *priv = image->priv;
- const GtkBitmask *changes;
+ GtkCssStyleChange *change;
GTK_WIDGET_CLASS (gtk_image_parent_class)->style_updated (widget);
- if (G_UNLIKELY (affects_icon == NULL))
- affects_icon = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_ICON);
-
- changes = _gtk_style_context_get_changes (gtk_widget_get_style_context (widget));
- if (changes == NULL || _gtk_bitmask_intersects (changes, affects_icon))
+ change = gtk_style_context_get_change (gtk_widget_get_style_context (widget));
+ if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_ICON))
icon_theme_changed (image);
priv->baseline_align = 0.0;
}
static void
gtk_label_style_updated (GtkWidget *widget)
{
- static GtkBitmask *affects_text_attrs = NULL;
GtkLabel *label = GTK_LABEL (widget);
GtkLabelPrivate *priv = label->priv;
GtkStyleContext *context;
- const GtkBitmask *changes;;
-
- if (G_UNLIKELY (affects_text_attrs == NULL))
- affects_text_attrs = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_TEXT_ATTRS);
+ GtkCssStyleChange *change;
GTK_WIDGET_CLASS (gtk_label_parent_class)->style_updated (widget);
context = gtk_widget_get_style_context (widget);
- changes = _gtk_style_context_get_changes (context);
+ change = gtk_style_context_get_change (context);
- if (changes == NULL || _gtk_bitmask_intersects (changes, affects_text_attrs) ||
+ if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_TEXT_ATTRS) ||
(priv->select_info && priv->select_info->links))
gtk_label_update_layout_attributes (label);
}
GdkFrameClock *frame_clock;
- const GtkBitmask *invalidating_context;
+ GtkCssStyleChange *invalidating_context;
};
enum {
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
}
-static void
-gtk_style_context_do_invalidate (GtkStyleContext *context,
- const GtkBitmask *changes)
+static GtkCssStyleChange magic_number;
+
+void
+gtk_style_context_validate (GtkStyleContext *context,
+ GtkCssStyleChange *change)
{
GtkStyleContextPrivate *priv;
if (priv->invalidating_context)
return;
- priv->invalidating_context = changes;
+ if (change)
+ priv->invalidating_context = change;
+ else
+ priv->invalidating_context = &magic_number;
g_signal_emit (context, signals[CHANGED], 0);
priv->invalidating_context = NULL;
}
-void
-gtk_style_context_validate (GtkStyleContext *context,
- const GtkBitmask *changes)
-{
- if (!_gtk_bitmask_is_empty (changes))
- gtk_style_context_do_invalidate (context, changes);
-}
-
/**
* gtk_style_context_invalidate:
* @context: a #GtkStyleContext.
void
gtk_style_context_invalidate (GtkStyleContext *context)
{
- GtkBitmask *changes;
-
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
gtk_style_context_clear_property_cache (context);
- changes = _gtk_bitmask_new ();
- changes = _gtk_bitmask_invert_range (changes,
- 0,
- _gtk_css_style_property_get_n_properties ());
- gtk_style_context_do_invalidate (context, changes);
- _gtk_bitmask_free (changes);
+ gtk_style_context_validate (context, NULL);
}
static gboolean
}
/**
- * _gtk_style_context_get_changes:
+ * gtk_style_context_get_change:
* @context: the context to query
*
* Queries the context for the changes for the currently executing
* GtkStyleContext::invalidate signal. If no signal is currently
- * emitted, this function returns %NULL.
+ * emitted or the signal has not been triggered by a CssNode
+ * invalidation, this function returns %NULL.
*
* FIXME 4.0: Make this part of the signal.
*
* Returns: %NULL or the currently invalidating changes
**/
-const GtkBitmask *
-_gtk_style_context_get_changes (GtkStyleContext *context)
+GtkCssStyleChange *
+gtk_style_context_get_change (GtkStyleContext *context)
{
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
+ if (context->priv->invalidating_context == &magic_number)
+ return NULL;
+
return context->priv->invalidating_context;
}
void gtk_style_context_save_to_node (GtkStyleContext *context,
GtkCssNode *node);
-const GtkBitmask *
- _gtk_style_context_get_changes (GtkStyleContext *context);
+GtkCssStyleChange *
+ gtk_style_context_get_change (GtkStyleContext *context);
GtkCssStyle * gtk_style_context_lookup_style (GtkStyleContext *context);
GtkCssValue * _gtk_style_context_peek_property (GtkStyleContext *context,
GType widget_type,
GParamSpec *pspec);
void gtk_style_context_validate (GtkStyleContext *context,
- const GtkBitmask*changes);
+ GtkCssStyleChange *change);
void gtk_style_context_clear_property_cache (GtkStyleContext *context);
gboolean _gtk_style_context_check_region_name (const gchar *str);
static void
gtk_text_view_style_updated (GtkWidget *widget)
{
- static GtkBitmask *affects_font = NULL;
GtkTextView *text_view;
GtkTextViewPrivate *priv;
PangoContext *ltr_context, *rtl_context;
GtkStyleContext *style_context;
- const GtkBitmask *changes;
-
- if (G_UNLIKELY (affects_font == NULL))
- affects_font = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_FONT);
+ GtkCssStyleChange *change;
text_view = GTK_TEXT_VIEW (widget);
priv = text_view->priv;
GTK_WIDGET_CLASS (gtk_text_view_parent_class)->style_updated (widget);
style_context = gtk_widget_get_style_context (widget);
- changes = _gtk_style_context_get_changes (style_context);
+ change = gtk_style_context_get_change (style_context);
- if ((changes == NULL || _gtk_bitmask_intersects (changes, affects_font)) &&
+ if ((change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_FONT)) &&
priv->layout && priv->layout->default_style)
{
gtk_text_view_set_attributes_from_style (text_view,
static void
gtk_tree_view_style_updated (GtkWidget *widget)
{
- static GtkBitmask *affects_size = NULL;
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
GList *list;
GtkTreeViewColumn *column;
GtkStyleContext *style_context;
- const GtkBitmask *changes;
-
- if (G_UNLIKELY (affects_size == NULL))
- affects_size = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP);
+ GtkCssStyleChange *change;
GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->style_updated (widget);
}
style_context = gtk_widget_get_style_context (widget);
- changes = _gtk_style_context_get_changes (style_context);
+ change = gtk_style_context_get_change (style_context);
- if (changes == NULL || _gtk_bitmask_intersects (changes, affects_size))
+ if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP))
{
for (list = tree_view->priv->columns; list; list = list->next)
{
if (widget->priv->context)
{
- const GtkBitmask *changes = _gtk_style_context_get_changes (widget->priv->context);
+ GtkCssStyleChange *change = gtk_style_context_get_change (widget->priv->context);
if (widget->priv->anchored)
{
- static GtkBitmask *affects_size, *affects_redraw, *affects_allocate;
-
- if (G_UNLIKELY (affects_size == NULL))
- {
- affects_size = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_SIZE);
- affects_allocate = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_CLIP);
- affects_redraw = _gtk_css_style_property_get_mask_affecting (GTK_CSS_AFFECTS_REDRAW);
- }
-
- if (changes == NULL || _gtk_bitmask_intersects (changes, affects_size))
+ if (change == NULL || gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE))
gtk_widget_queue_resize (widget);
- else if (_gtk_bitmask_intersects (changes, affects_allocate))
+ else if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_CLIP))
gtk_widget_queue_allocate (widget);
- else if (_gtk_bitmask_intersects (changes, affects_redraw))
+ else if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_REDRAW))
gtk_widget_queue_draw (widget);
}
}
static void
gtk_window_style_updated (GtkWidget *widget)
{
- const GtkBitmask *changes = _gtk_style_context_get_changes (gtk_widget_get_style_context (widget));
+ GtkCssStyleChange *change = gtk_style_context_get_change (gtk_widget_get_style_context (widget));
GTK_WIDGET_CLASS (gtk_window_parent_class)->style_updated (widget);
- if (changes == NULL || _gtk_bitmask_get (changes, GTK_CSS_PROPERTY_ICON_THEME))
+ if (change == NULL || gtk_css_style_change_changes_property (change, GTK_CSS_PROPERTY_ICON_THEME))
update_themed_icon (GTK_WINDOW (widget));
}